#pragma once
#include <boost/noncopyable.hpp>

namespace ja2
{
	//! Singleton template class. Is not thread-safe.
	template<typename T>
	class Singleton : boost::noncopyable
	{
		// Attributes
	private:
		//! Singleton object.
		static Singleton<T> * m_pInstance;
		//! Object which singleton is holding.
		T * const m_pObject;

		// Operations
	public:
		//! Get the instance.
		static Singleton<T> &instance();
		//! Get the instance pointer.
		static Singleton<T> *instance_ptr();

		// Operators
	public:
		T &operator*() const;
		T *operator->() const;

		// Construction/Destruction
	public:
		Singleton(T *pObject = nullptr);
		~Singleton();
	};

	template<typename T>
	Singleton<T> * Singleton<T>::m_pInstance = nullptr;

	template<typename T>
	Singleton<T>::Singleton(T *pObject)
		: m_pObject(pObject)
	{
		m_pInstance = this;
	}

	template<typename T>
	Singleton<T>::~Singleton()
	{
		delete m_pObject;
	}

	template<typename T>
	inline Singleton<T> &Singleton<T>::instance()
	{
		return *m_pInstance;
	}

	template<typename T>
	inline Singleton<T> *Singleton<T>::instance_ptr()
	{
		return m_pInstance;
	}

	template<typename T>
	T & Singleton<T>::operator*() const
	{
		return *m_pObject;
	}

	template<typename T>
	T *Singleton<T>::operator->() const
	{
		return m_pObject;
	}
} /*ja2*/
